home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
et
/
et3_0-a1.lha
/
et3
/
src
/
Document.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-07-10
|
8KB
|
393 lines
#ifdef __GNUG__
#pragma implementation
#endif
#include "Document.h"
#include "Class.h"
#include "ImageItem.h"
#include "FileDialog.h"
#include "System.h"
#include "CommandProcessor.h"
#include "WindowSystem.h"
#include "Env.h"
#include "ProgressDialog.h"
#include "OrdColl.h"
#include "CLib.h"
#include "Data.h"
#include "MenuBar.h"
#include "Menu.h"
#include "CmdNo.h"
#include "String.h"
#include "Application.h"
#include "Alert_e.h"
extern SmartBitmap gFileIcon;
static FileDialog *loadDialog, *saveDialog;
ONEXIT(Document)
{
SafeDelete(loadDialog);
SafeDelete(saveDialog);
}
static int untitledCnt;
//---- Document ----------------------------------------------------------------
NewAbstractMetaImpl(Document,Manager, (T(docType), TP(docData)));
Document::Document(const Symbol &dt)
{
docType= dt;
docData= new FileData(form("untitled.%d", untitledCnt++), TRUE);
Manager::SetName(GetBaseName());
SetOnDismiss(eMgrIconize);
}
Document::~Document()
{
SafeDelete(docData);
}
CommandProcessor *Document::MakeCmdProcessor()
{
int n= Env::GetValue("Document.UndoLevel", 1);
if (n == 1)
return new CommandProcessor1;
if (n > 100)
return new CommandProcessorN;
return new CommandProcessor10(n);
}
FileDialog *Document::MakeFileDialog(FileDialogType)
{
return gApplication->MakeFileDialog();
}
char *Document::GetBaseName()
{
return docData->ShortName();
}
int Document::UniqueId()
{
return docData->UniqueId();
}
bool Document::IsUntitled()
{
return docData->IsUntitled();
}
bool Document::IsConverted()
{
if (docType == cDocTypeAscii && docData->IsAscii())
return FALSE;
return docData->Type() != docType;
}
void Document::SetData(Data *fd)
{
if (fd && fd != docData) {
SafeDelete(docData);
docData= (Data*) fd->DeepClone();
}
Manager::SetName(GetBaseName());
}
VObject *Document::DoMakeIconContent()
{
return DoMakeIcon(GetName());
}
VObject *Document::DoMakeIcon(char*)
{
return new ImageItem(gFileIcon, 13);
}
//---- Menus -------------------------------------------------------------------
MenuBar *Document::DoMakeMenuBar()
{
MenuBar *mb= new MenuBar;
mb->AddMenu(MakeMenu(cHELPMENU));
mb->AddMenu(MakeMenu(cFILEMENU));
mb->AddMenu(MakeMenu(cEDITMENU));
mb->AddMenu(MakeMenu(cAPPMENU));
return mb;
}
Menu *Document::MakeMenu(int menuId)
{
Menu *m;
switch (menuId) {
case cFILEMENU:
m= new Menu(cFILEMENU, "File");
m->AppendItems(
"New@N", cNEW,
"Open ...@O", cOPEN,
"-",
"Load ...@L", cLOAD,
"Save@S", cSAVE,
"Save As ...", cSAVEAS,
"Revert", cREVERT,
"Close", cCLOSE,
"-",
"Print ...@P", cPRINT,
"-",
"Quit@Q", cQUIT,
0);
break;
default:
m= Manager::MakeMenu(menuId);
}
return m;
}
void Document::DoSetupMenu(Menu *m)
{
Manager::DoSetupMenu(m);
GetCmdP()->DoSetupMenu(m);
if (Modified()) {
m->EnableItem(cSAVE);
if (!IsUntitled())
m->EnableItem(cREVERT);
}
m->EnableItems(cLOAD, cSAVEAS, cPRINT, 0);
}
Command *Document::DoMenuCommand(int cmd)
{
switch(cmd) {
case cSAVE: Save(); break;
case cSAVEAS: SaveAs(); break;
case cLOAD: Load(); break;
case cREVERT: Revert(); break;
case cCLOSE: Close(); break;
default:
return Manager::DoMenuCommand(cmd);
}
return gNoChanges;
}
void Document::CollectParts(Collection *col)
{
Manager::CollectParts(col);
if (docData)
col->Add(docData);
}
void Document::ExtCommand(int c, char *req, char *args, int l, char *&rc, int &rl)
{
if (strcmp(req, "load") == 0)
Load(args);
else if (strcmp(req, "save") == 0)
Save();
else
Manager::ExtCommand(c, req, args, l, rc, rl);
}
bool Document::Modified()
{
return GetCmdP()->Modified();
}
bool Document::SavedChanges()
{
if (Modified()) {
switch (ShowAlert(eAlertCaution, "Save changes to @B%s @P?", docData->Name())) {
case cIdYes:
if (Save())
return TRUE;
return FALSE; // save cancelled -> cancel all
case cIdNo:
GetCmdP()->Finish();
return TRUE;
case cIdCancel:
return FALSE;
}
}
return TRUE;
}
bool Document::Load(char *filename, bool unique)
{
if (filename) {
Data *d= new FileData(filename);
bool b= LoadData(d, unique);
delete d;
return b;
}
return LoadData(0, unique);
}
bool Document::LoadData(Data *data, bool unique)
{
if (! SavedChanges())
return FALSE;
if (data == 0) {
if (loadDialog == 0)
loadDialog= MakeFileDialog(eFDTypeRead);
if (loadDialog->ShowInWindow(eFDRead, GetWindow(), this) != cIdOk)
return FALSE;
data= loadDialog->GetData();
}
if (CanLoad(data)) {
if (data->UniqueId() == 0) {
ShowAlert(eAlertNote, "something wrong with @B%s @P\n%s", data->Name(),
gSystem->GetErrorStr());
return FALSE;
}
if (unique) {
Document *doc= gApplication->FindDocument((int)data->UniqueId());
if (doc && !DoFileIsAlreadyOpen(doc, data->FullName()))
return FALSE;
}
AboutToLoad(data);
SetData(data);
gProgress->Start(form("Reading: %s", GetBaseName()), data->SizeHint());
DoReadData(data);
gProgress->Stop();
gWindowSystem->Update();
} else
gApplication->OpenDocument(data->FullName());
return TRUE;
}
void Document::AboutToLoad(Data*)
{
}
bool Document::Close() // return TRUE if OK
{
if (IsOpen()) {
if (SavedChanges())
return Manager::Close();
return TRUE;
}
return FALSE;
}
bool Document::Save()
{
if (Modified() && (IsUntitled() || IsConverted()))
return SaveAs();
if (! Modified()) {
ShowAlert(eAlertNote, "No changes since last save");
return TRUE;
}
if (! docData->IsWritable()) {
ShowAlert(eAlertNote, "Document @B%s @Pis not writable\n%s",
docData->Name(), gSystem->GetErrorStr());
return FALSE;
}
if (Env::GetValue("Document.MakeBackup", FALSE))
MakeBackup(docData->FullName(), 0);
Store();
return TRUE;
}
bool Document::SaveAs()
{
if (saveDialog == 0)
saveDialog= MakeFileDialog(eFDTypeWrite);
if (saveDialog->ShowInWindow(eFDWrite, GetWindow(), this) == cIdOk) {
SetData(saveDialog->GetData());
Store();
return TRUE;
}
return FALSE;
}
void Document::Revert()
{
if (Modified() && ShowAlert(eAlertCaution, "Discard all changes of @B%s @P?",
GetBaseName()) == cIdYes) {
GetCmdP()->Finish();
Load(docData->FullName(), FALSE);
}
}
//---- Load/Store Documents -----------------------------------------------------
void Document::MakeBackup(char *path, char*)
{
gSystem->Rename(path, form("%s%%", path));
}
bool Document::CanLoad(Data *data)
{
if (GetDocumentType() == data->Type())
return TRUE;
if (GetDocumentType() == cDocTypeAscii && data->IsAscii())
return TRUE;
return FALSE;
}
bool Document::DoFileIsAlreadyOpen(Document *shown, char *name)
{
ShowAlert(eAlertNote, "Document @B%s @Pis already open", name);
if (shown != this)
shown->Show();
return FALSE;
}
void Document::Store()
{
GetCmdP()->Finish();
gProgress->Start(form("Writing: %s", GetBaseName()), 1000000);
if (!docData->IsUntitled()) {
gSystem->Rename(docData->FullName(), form("%s%%", docData->FullName()));
}
OStream to(docData->GetStreamBufForWriting(), TRUE);
if (DoWrite(to, docData)) {
if (!Env::GetValue("Document.MakeBackup", FALSE)) {
CLib::Unlink(form("%s%%", docData->FullName()));
}
}
gProgress->Stop();
}
bool Document::DoWrite(OStream& to, Data*)
{
to << cMagic SP << docType SP << gApplication->ProgramName() NL;
return TRUE;
}
bool Document::DoReadData(Data *data)
{
IStream from(data->GetStreamBufForReading(), 0, TRUE);
return DoRead(from, data);
}
bool Document::DoRead(IStream &from, Data*)
{
char c;
// overread magic cookie
while (from.get(c))
if (c == '\n')
break;
return TRUE;
}